package com.ww.demo;

import java.util.concurrent.*;

/**
 * 线程创建三种方法和线程池创建四种方法
 * 1.继承Thread; 2.实现Runnable ;3.实现Callable
 * 线程池ThreadPoolExecutor
 * 阿里推荐方式：
 * （1）newCachedThreadPool 创建一个可缓存的线程池，如果线程池长度超过处理需求，可灵活回收空闲线程，若无可回收，则新建线程。
 * （2）newFixedThreadPool 创建一个定长线程池，可控制线程最大并发数，超出的线程会在队列中等待
 * （3）newScheduledThreadPool 创建一个定长线程池，支持定时及周期性任务执行
 * （4）newSingleThreadExecutor 创建一个单线程化的线程池，它只会唯一的工作线程来执行任务，保证所有任务按照指定顺序（FIFO，LIFO，优先级）执行
 */
public class ThreadTest {
    // threadpool 01  线程长度无限大，可回收利用
    ExecutorService cachedThreadPool= Executors.newCachedThreadPool();
    // threadpool 02  定长线程池，超出会在队列中等待
    ExecutorService fixedThreadPool= Executors.newFixedThreadPool(10);
    // threadpool 03  定长线程池，支持定时周期性执行任务
    ScheduledExecutorService scheduledThreadPool= Executors.newScheduledThreadPool(10);
    // threadpool 04  单线程化的线程池，只会用唯一的工作线程来执行任务
    static ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

    // 推荐方式
    static ExecutorService es = new ThreadPoolExecutor(5, 10, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<Runnable>(10),Executors.defaultThreadFactory(), new ThreadPoolExecutor.DiscardPolicy());

    /**
     * threadPool 01
     */
    public static void newThreadPool01() {
        es.execute(()->{
            System.out.println("create a thread");
        });
    }
    /**
     * thread 01
     */
    public void newThread01() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("method01 to create thread.");
            }
        }).start();
    }

    /**
     * thread 02
     */
    public void newThread02() {
        Thread02 thread02 = new Thread02();
        thread02.start();
    }

    class Thread02 extends Thread {
        @Override
        public void run() {
            System.out.println("method02 to create thread.");
        }
    }

    /**
     * thread 03
     */
    public void newThread03() {
        Thread03 thread03 = new Thread03();
        new Thread(thread03).start();
    }

    class Thread03 implements Runnable {
        @Override
        public void run() {
            System.out.println("method03 to create thread.");
        }
    }

    /**
     * thread 04
     */
    public void newThread04() {
        Thread04 thread04 = new Thread04();
        FutureTask futureTask =  new FutureTask(thread04);
        new Thread(futureTask).start();
        try {
           Object obj = futureTask.get(); // 获取返回值
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

    }


    class Thread04 implements Callable{

        @Override
        public Object call() throws Exception {
            return "run over";
        }
    }




    public static void main(String[] args) {
        newThreadPool01();
//        singleThreadExecutor.execute(new Runnable() {
//            @Override
//            public void run() {
//                System.out.println("hello");
//            }
//        });
    }

}
